package com.premierleaguestats.client;

import java.util.ArrayList;

import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.visualization.client.AbstractDataTable;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.VisualizationUtils;
import com.google.gwt.visualization.client.visualizations.corechart.PieChart;
import com.google.gwt.visualization.client.visualizations.corechart.AxisOptions;
import com.google.gwt.visualization.client.visualizations.corechart.LineChart;
import com.google.gwt.visualization.client.visualizations.corechart.Options;

public class TeamStats extends Composite {

	private HorizontalPanel teamStats = new HorizontalPanel();
	private VerticalPanel vPanel = new VerticalPanel();
	private VerticalPanel graphPanel = new VerticalPanel();
	private StatsServiceAsync gameSvc = GWT.create(StatsService.class);
	private Label errorMsgLabel = new Label();
	private ListBox listBox = new ListBox();
	private ListBox seasonListBox = new ListBox();
	private RadioButton pointsButton = new RadioButton("show", "Show points"); // bar chart
	private RadioButton gameButton = new RadioButton("show", "Show games"); // pie chart
	private RadioButton positionButton = new RadioButton("show", "Show position"); // line chart
	private int selectedIndex = 0;
	private int selectedSeasonIndex = 0;

	static private TeamStats instance = null;

	public TeamStats(){
		initPage();
		initWidget(teamStats);
	}

	public static TeamStats getInstance() {
		if(instance == null){
			instance = new TeamStats();
		}
		return instance;
	}

	private void initPage(){

		listBox.addItem("Select a team");
		listBox.addItem("Arsenal");
		listBox.addItem("Aston Villa");
		listBox.addItem("Birmingham");
		listBox.addItem("Blackburn");
		listBox.addItem("Blackpool");
		listBox.addItem("Bolton");
		listBox.addItem("Bradford");
		listBox.addItem("Burnley");
		listBox.addItem("Charlton");
		listBox.addItem("Chelsea");
		listBox.addItem("Coventry");
		listBox.addItem("Crystal Palace");
		listBox.addItem("Derby");
		listBox.addItem("Everton");
		listBox.addItem("Fulham");
		listBox.addItem("Hull");
		listBox.addItem("Ipswich");
		listBox.addItem("Leeds");
		listBox.addItem("Leicester");
		listBox.addItem("Liverpool");
		listBox.addItem("Man City");
		listBox.addItem("Man Utd");
		listBox.addItem("Middlesbrough");
		listBox.addItem("Newcastle");
		listBox.addItem("Norwich");
		listBox.addItem("Portsmouth");
		listBox.addItem("QPR");
		listBox.addItem("Reading");
		listBox.addItem("Sheffield Utd");
		listBox.addItem("Southampton");

		// Add handler to listbox
		listBox.addChangeHandler(new ChangeHandler(){

			public void onChange(ChangeEvent event){
				selectedIndex = listBox.getSelectedIndex();
				//System.out.println("listBoxListener: " + listBox.getItemText(selectedIndex));
				positionButton.setChecked(false);

			}
		});

		// Add handler to radio buttons
		ClickHandler handler = new ClickHandler() {

			@Override
			public void onClick(ClickEvent e) {

				if(e.getSource()==pointsButton){
					vPanel.remove(seasonListBox);
					System.out.println("pointsButton pressed!");
				}else if(e.getSource()==positionButton){
					vPanel.remove(seasonListBox);
					System.out.println("positionButton Pressed!");
					if(selectedIndex != 0){
						getTeamStats(listBox.getItemText(selectedIndex));
					}
				}else if(e.getSource()==gameButton){

					seasonListBox.clear();
					seasonListBox.addItem("Choose a season");
					seasonListBox.addItem("S0001");
					seasonListBox.addItem("S0102");
					seasonListBox.addItem("S0203");
					seasonListBox.addItem("S0304");
					seasonListBox.addItem("S0405");
					seasonListBox.addItem("S0506");
					seasonListBox.addItem("S0607");
					seasonListBox.addItem("S0708");
					seasonListBox.addItem("S0809");
					seasonListBox.addItem("S0910");
					seasonListBox.addItem("S1011");
					seasonListBox.addItem("S1112");


					vPanel.add(seasonListBox);

					seasonListBox.addChangeHandler(new ChangeHandler(){

						@Override
						public void onChange(ChangeEvent event) {
							selectedSeasonIndex = seasonListBox.getSelectedIndex();
							positionButton.setChecked(false);
							if(selectedSeasonIndex !=0){
								DatabasePie(listBox.getItemText(selectedIndex), seasonListBox.getItemText(selectedSeasonIndex));
							}
						}
					});
				}
			}
		};

		pointsButton.addClickHandler(handler);
		positionButton.addClickHandler(handler);
		gameButton.addClickHandler(handler);

		// adding listbox to the panel
		vPanel.add(listBox);
		vPanel.setPixelSize(600, 100);

		// adding buttons to the panel
		vPanel.add(positionButton);
		//		vPanel.add(pointsButton);
		vPanel.add(gameButton);

		teamStats.add(vPanel);
		teamStats.add(graphPanel);
		teamStats.setPixelSize(1000, 400);

	}

	/*
	 * Draws the line graph
	 */
	private void drawLineGraph(final ArrayList<TeamStatsData> result, final String teamName){

		graphPanel.clear();

		Runnable onLoadCallback = new Runnable(){

			@Override
			public void run() {

				AbstractDataTable data = createLineTable(result, teamName);
				Options chartOptions = createLineOptions();
				LineChart lineChart = new LineChart (data, chartOptions);
				graphPanel.clear();
				graphPanel.add(lineChart);
			}
		};
		VisualizationUtils.loadVisualizationApi(onLoadCallback, LineChart.PACKAGE);
	}

	/*
	 * Create options Line graph
	 */
	private Options createLineOptions(){

		Options options = Options.create(); 
		options.setWidth(600); 
		options.setHeight(360); 
		options.setTitle("Premier League Positions"); 
		options.setPointSize(10);

		AxisOptions hAxisOptions = AxisOptions.create();
		hAxisOptions.setTitle("Season");

		AxisOptions vAxisOptions = AxisOptions.create();
		vAxisOptions.setDirection(-1);
		vAxisOptions.setMinValue(1);
		vAxisOptions.setMaxValue(20);
		vAxisOptions.setTitle("Position");
		options.setHAxisOptions(hAxisOptions);
		options.setVAxisOptions(vAxisOptions);
		return options; 
	}

	/*
	 * Create a data table to draw line 
	 */
	private AbstractDataTable createLineTable(ArrayList<TeamStatsData> result, String teamName){

		DataTable data = DataTable.create();
		data.addColumn(ColumnType.STRING); // for-loop TeamName
		data.addColumn(ColumnType.NUMBER, teamName);
		data.addRows(result.size()); // Number of seasons
		for(int i = 0; i < result.size(); i++){
			data.setValue(i, 1 , result.get(i).getData());
			data.setValue(i, 0, result.get(i).getSeason());	
		}
		return data;
	}

	/*
	 * Draw the pie graph
	 */
	private void drawPieGraph(final TeamStatsData result, final String teamName){

		graphPanel.clear();

		Runnable onLoadCallback = new Runnable(){

			@Override
			public void run() {

				AbstractDataTable data = createPieTable((SeasonGames) result, teamName);
				Options chartPieOptions = createPieOptions(teamName, result.getSeason());
				PieChart pieChart = new PieChart(data, chartPieOptions);
				graphPanel.clear();
				graphPanel.add(pieChart);
			}

		};
		VisualizationUtils.loadVisualizationApi(onLoadCallback, PieChart.PACKAGE);
	}

	/*
	 * Create options for pie chart
	 */
	private Options createPieOptions(String teamName, String season){

		Options options = Options.create(); 
		options.setWidth(600); 
		options.setHeight(360);
		options.setColors("GREEN", "RED", "YELLOW");
		options.setTitle("Game statistics for: "+ teamName+ ", Season:"+ season); 

		return options; 
	}

	/*
	 * Create data table for pie chart
	 */
	private AbstractDataTable createPieTable(SeasonGames result, String teamName){

		DataTable data = DataTable.create();
		data.addColumn(ColumnType.STRING); // for-loop TeamName
		data.addColumn(ColumnType.NUMBER);
		data.addRows(3); // Number of seasons

		data.setValue(0, 0, "Wins");
		data.setValue(0, 1, result.getWin());
		data.setValue(1, 0, "Losses");
		data.setValue(1, 1, result.getLoss());
		data.setValue(2, 0, "Draw");
		data.setValue(2, 1, result.getDraw());

		return data;

	}

	/*
	 * Server call to get a teams position from all seasons
	 */
	private void getTeamStats(String teamName){
		// Initialize the service proxy.
		final String t = teamName;
		System.out.println("DATABASETEST");
		if (gameSvc == null) {
			gameSvc = GWT.create(StatsService.class);
		}
		// Set up the callback object.
		AsyncCallback<ArrayList<TeamStatsData>> callback = new AsyncCallback<ArrayList<TeamStatsData>>() {

			public void onFailure(Throwable caught) {
				System.out.println("OnFailure");

				String details = caught.getMessage();
				errorMsgLabel.setText("Error: " + details);
				errorMsgLabel.setVisible(true);
			}
			@Override
			public void onSuccess(ArrayList<TeamStatsData> result) {
				graphPanel.clear();
				drawLineGraph(result, t);
			}
		};
		System.out.println("gamesvc b4");
		gameSvc.getDb(teamName, callback);
		System.out.println("gamesvca8");
	}

	/*
	 * Server call to get all matches a team has played during a season
	 */
	private void DatabasePie(String teamName, String season){
		// Initialize the service proxy.
		final String t = teamName;

		System.out.println("DATABASEPIE");
		if (gameSvc == null) {
			gameSvc = GWT.create(StatsService.class);
		}
		// Set up the callback object.
		AsyncCallback<SeasonGames> callback = new AsyncCallback<SeasonGames>() {

			public void onFailure(Throwable caught) {
				System.out.println("OnFailure");

				String details = caught.getMessage();
				errorMsgLabel.setText("Error: " + details);
				errorMsgLabel.setVisible(true);
			}
			@Override
			public void onSuccess(SeasonGames result) {
				if(result!=null){
					graphPanel.clear();
					drawPieGraph(result, t);
				}else{
					Window.alert("The chosen team didn't play in premier Leauge");
				}
			}
		};

		System.out.println("gamespieb4");
		gameSvc.getSeasonGames(teamName,season, callback);
		System.out.println("gamespiea8");
	}
}

